玩转ASP.NET Core中的日志组件

您所在的位置:网站首页 net core program 玩转ASP.NET Core中的日志组件

玩转ASP.NET Core中的日志组件

2024-07-02 10:18:38| 来源: 网络整理| 查看: 265

简介

日志组件,作为程序员使用频率最高的组件,给程序员开发调试程序提供了必要的信息。ASP.NET Core中内置了一个通用日志接口ILogger,并实现了多种内置的日志提供器,例如

Console Debug EventSource EventLog TraceSource Azure App Service

除了内置的日志提供器,ASP.NET Core还支持了多种第三方日志工具,例如

elmah.io Gelf JSNLog KissLog.net Loggr NLog Serilog

开发人员在ASP.Net Core中可以自由指定日志提供器,并将日志发送到指定的位置。 本篇博文中,我们将由浅入深的介绍ASP.Net Core中通用日志接口,最后我们将实现一些自定义的日志提供器(Log Provider)。

使用系统提供的内置日志提供器 日志级别(Log Level)

ASP.NET Core中提供了6种日志级别,分别是Trace, Debug, Information, Warning, Error, Critical。以下是他们的具体使用场景

日志级别 常用场景 Trace 记录一些对程序员调试问题有帮助的信息, 其中可能包含一些敏感信息, 所以应该避免在生产环境中启用Trace日志 Debug 记录一些在开发和调试阶段有用的短时变量(Short-term usefulness), 所以除非为了临时排除生产环境的故障,开发人员应该尽量避免在生产环境中启用Debug日志 Information 记录应用程序的一些流程, 例如,记录当前api请求的url Warning 记录应用程序中发生的不正常或者未预期的事件信息。这些信息中可能包含错误消息或者错误产生的条件, 例如, 文件未找到 Error 记录应用程序中某个操作产生的错误和异常信息。 Critical 记录一些需要立刻修复的问题。例如数据丢失,磁盘空间不足。 如何创建日志

为了创建一个日志,我们首先需要通过依赖注入获取一个实现ILogger的泛型接口对象。

已以下代码为例, 在ValuesController的构造函数中,我们注入了一个ILogger的日志记录器

[Route("api/[controller]")] [ApiController] public class ValuesController : ControllerBase { private readonly ILogger _logger = null; public ValuesController(ILogger logger) { _logger = logger; } // GET api/values [HttpGet] public ActionResult Get() { _logger.LogInformation("[Test Log]Getting items."); return new string[] { "value1", "value2" }; } }

然后我们使用ILogger接口提供的LogInformation方法添加了一个Information类型日志"[Test Log]Getting items"。

注:ILogger为了提供了6个可用的输出日志方法,分别对应了6个不同的日志级别

LogTrace LogDebug LogInformation LogWarning LogError LogCritical!

下面我们使用Kestral服务器启动项目

项目产生的日志如下,我们手动输出的日志出现在控制台中。

日志配置

可能针对以上的代码,有些同学可能有疑问,我们没有在Startup.cs中注入任何日志提供器,但是日志却正常产生了。这是由于Program.cs中默认使用WebHost.CreateDefaultBuilder方法添加了2个日志提供器。

默认日志提供器

当创建一个新的ASP.NET Core WebApi项目,我们通常在Program.cs中看到以下代码。

public class Program { public static void Main(string[] args) { CreateWebHostBuilder(args).Build().Run(); } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup(); }

下面我们看一下WebHost.CreateDefaultBuilder的源代码

public static IWebHostBuilder CreateDefaultBuilder(string[] args) { var builder = new WebHostBuilder() .UseKestrel() .UseContentRoot(Directory.GetCurrentDirectory()) .ConfigureAppConfiguration((hostingContext, config) => { var env = hostingContext.HostingEnvironment; config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true); if (env.IsDevelopment()) { var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName)); if (appAssembly != null) { config.AddUserSecrets(appAssembly, optional: true); } } config.AddEnvironmentVariables(); if (args != null) { config.AddCommandLine(args); } }) .ConfigureLogging((hostingContext, logging) => { logging.UseConfiguration(hostingContext.Configuration.GetSection("Logging")); logging.AddConsole(); logging.AddDebug(); }) .UseIISIntegration() .UseDefaultServiceProvider((context, options) => { options.ValidateScopes = context.HostingEnvironment.IsDevelopment(); }) .ConfigureServices(services => { services.AddTransient(); }); return builder; }

你会发现代码中通过logging.AddConsole和logging.AddDebug默认配置了Console和Debug类型的日志提供器,这也就是为什么我们没有注入任何日志提供器,日志却能正常产生了。

手动添加日志提供器

看了以上代码后,你应该可以也清楚了如何自己添加其他内置的日志提供器。我们只需要在Program.cs中使用ConfigureLogging方法就可以配置我们需要的日志提供器了。

例:

public class Program { public static void Main(string[] args) { CreateWebHostBuilder(args).Build().Run(); } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .ConfigureLogging((hostingContext, logging) => { logging.AddConsole(); logging.AddDebug(); logging.AddEventSourceLogger(); }) .UseStartup(); }

除了在Program.cs添加日志提供器之外,我们还可以在Startup.cs中添加日志提供器。 在Startup.cs中,我们可以为Configure方法添加第三个参数ILoggerFactory loggerFactory, 并使用该参数添加日志提供器。

例:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } loggerFactory.AddConsole(); loggerFactory.AddDebug(); app.UseMvc(); } 配置文件及日志级别过滤

ASP.NET Core默认会从appSetting.json中的Logging属性读取日志的配置(当然你也可以从其他文件中读取配置),这里设置了不同的日志提供器产生的最低的日志级别,配置样例如下。

{ "Logging": { "Debug": { "LogLevel": { "Default": "Information" } }, "Console": { "LogLevel": { "Microsoft.AspNetCore.Mvc.Razor.Internal": "Warning", "Microsoft.AspNetCore.Mvc.Razor.Razor": "Debug", "Microsoft.AspNetCore.Mvc.Razor": "Error", "Default": "Trace" } }, "LogLevel": { "Default": "Debug" } } }

以上代码中的Debug表示Debug日志提供器, Console表示Console日志提供器, 最后一个LogLevel表示其他日志提供器通用。 Debug中的Default设置为Information, 即Debug中产生的日志最低级别是Information, 低于Information级别的日志不会输出。Console中的配置同理。

自定义日志组件

在学习了以上基础知识之后,我们应该对内置的日志提供器有了简单的认识。下面我们尝试自定义2个日志提供器。 在ASP.NET Core中,我们可以通过实现ILogger, ILoggerProvider2个接口来创建我们自己的日志提供器。

编写一个自定义样式的控制台日志组件

这里我们希望添加一个在控制台中输出的日志,但是和内置Console类型日志的区别是我们为不同的日志类型设置了不同的颜色。

首先我们创建一个新的Api项目ColoredConsoleLoggerSample

然后我们创建一个针对不同日志级别的字体颜色配置类ColoredConsoleLoggerConfiguration, 代码如下

public class ColoredConsoleLoggerConfiguration { public LogLevel LogLevel { get; set; } = LogLevel.Warning; public ConsoleColor Color { get; set; } = ConsoleColor.Yellow; }

这个类中定义了针对不同日志类型设置不同的字体颜色。

然后我们创建一个日志类ColoredConsoleLogger, 它实现了ILogger接口,代码如下

public class ColoredConsoleLogger : ILogger { private readonly string _name; private readonly ColoredConsoleLoggerConfiguration _config; public ColoredConsoleLogger(string name, ColoredConsoleLoggerConfiguration config) { _name = name; _config = config; } public IDisposable BeginScope(TState state) { return null; } public bool IsEnabled(LogLevel logLevel) { return logLevel == _config.LogLevel; } public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) { if (!IsEnabled(logLevel)) { return; } var color = Console.ForegroundColor; Console.ForegroundColor = _config.Color; Console.WriteLine($"{logLevel.ToString()} - {_name} - {formatter(state, exception)}"); Console.ForegroundColor = color; } }

代码解释

ColoredConsoleLogger仅针对一种日志级别 只要当前产生的日志级别和ColoredConsoleLogger中定义的日志级别一样时,日志才会输出,这里我们是用IsEnable方法判断的 Log是ILogger接口中定义的方法,我们就是在这个方法中输出日志的 这里我们在输入日志前记录下了当前控制台的原始字体颜色, 当输出日志完成之后,我们将字体颜色恢复成了原来的颜色

然后我们添加一个Logger提供器类ColoredConsoleLoggerProvider,代码如下

public class ColoredConsoleLoggerProvider : ILoggerProvider { private readonly ColoredConsoleLoggerConfiguration _config; public ColoredConsoleLoggerProvider(ColoredConsoleLoggerConfiguration config) { _config = config; } public ILogger CreateLogger(string categoryName) { return new ColoredConsoleLogger(categoryName, _config); } public void Dispose() { } }

代码解释

ColoredConsoleLoggerProvider仅针对一种日志级别 CreateLogger是ILoggerProvider接口中定义的方法,它是用来返回一个日志生成器的

最后我们修改Startup.cs中的Configure方法, 代码如下

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } loggerFactory.AddProvider(new ColoredConsoleLoggerProvider(new ColoredConsoleLoggerConfiguration { LogLevel = LogLevel.Information, Color = ConsoleColor.Blue })); loggerFactory.AddProvider(new ColoredConsoleLoggerProvider(new ColoredConsoleLoggerConfiguration { LogLevel = LogLevel.Debug, Color = ConsoleColor.Gray })); app.UseMvc(); }

这里我们添加了2个日志日志提供器,分别是针对Information级别日志和Debug级别日志的

最终效果

我们的日志根据我们预设的字体颜色正确的显示了出来

编写一个与SignalR集成的实时日志组件

下面我们再来自定义一个与SignalR集成的日志提供器,我们希望产生的日志通过一个SignalR服务器推送到一个网页中。

首先我们创建一个ASP.NET Core WebApi项目,命名为SignalrServer, 创建之后,我们右键项目属性,修改App Url为http://localhost:5000

然后我们创建一个LogHub类,它集成自Hub类,代码如下

public class LogHub : Hub { public async Task WriteLog(Log log) { await Clients.All.SendAsync("showLog", log); } } public class Log { public LogLevel Level { get; set; } public string Content { get; set; } }

代码解释

这里我们创建了一个写日志的方法,它会把日志推送到所有连接到SignalR服务器的客户端,并调用客户端的showLog方法来展示推送的日志信息。

然后我们修改Startup.cs文件,代码如下

public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddCors(); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); services.AddSignalR(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseCors(p => p.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader().AllowCredentials()); app.UseSignalR(routes => { routes.MapHub("/logHub"); }); app.UseMvc(); } }

代码解释

我们通过service.AddSignalR注册了SignalR服务 我们通过app.UserSignalR方法注册一个logHub 这里我们启用了CORS, 因为需要提供跨域访问

然后我们创建一个另外一个ASP.NET Core WebApi项目, SignalRLoggerSample

项目创建成功之后,我们右键点击项目属性,并设置App URL为http://localhost:5001

然后我们使用Package Console Manager, 安装Microsoft.AspNetCore.SignalR.Client

PM> install-package Microsoft.AspNetCore.SignalR.Client

为了创建一个SignalR日志提供器, 我们分别创建一个SignalRLogger类和一个SignalRLoggerProvider类, 代码如下

SignalRLogger.cs

public class SignalRLogger : ILogger { HubConnection connection; public SignalRLogger() { connection = new HubConnectionBuilder() .WithUrl("http://localhost:5000/LogHub") .Build(); } public IDisposable BeginScope(TState state) { return null; } public bool IsEnabled(LogLevel logLevel) { return true; } public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) { if (!IsEnabled(logLevel)) { return; } connection.StartAsync().Wait(); var task = connection.SendAsync("writeLog", new { Level = logLevel, Content = formatter(state, exception) }); task.Wait(); } }

SignalRLoggerProvider.cs

public class SignalRLoggerProvider : ILoggerProvider { public SignalRLoggerProvider() { } public ILogger CreateLogger(string categoryName) { return new SignalRLogger(); } public void Dispose() { } }

代码解释

这里使用HubConnectionBuilder创建了一个SignalR连接 连接启动成功之后,我们使用connection.SendAsync方法,将当前产生的日志信息发送到SignalR服务器

添加完成之后,我们在wwwroot文件夹中创建一个index.html, 在其中引入jquery和signalr的js库,并指定连接的signalR服务器是http://localhost:5000/logHub

index.html

Logs var levels = [ { level: 0, name: 'Trace', backgroundColor: 'gray' }, { level: 1, name: 'Debug', backgroundColor: 'green' }, { level: 2, name: 'Information', backgroundColor: 'blue' }, { level: 3, name: 'Warning', backgroundColor: 'yellow' }, { level: 4, name: 'Error', backgroundColor: 'orange' }, { level: 5, name: 'Critical', backgroundColor: 'red' }, ]; function getLevelName(level) { return levels.find(function (o) { return o.level == level; }).name; } function getLevelColor(level) { return levels.find(function (o) { return o.level == level; }).backgroundColor; } var connection = new signalR.HubConnectionBuilder().withUrl("http://localhost:5000/logHub").build(); connection.on("showLog", function (message) { var div = "[" + getLevelName(message.level) + "]:" + message.content + ""; $("#content").append(div); }); connection.start().catch(function (err) { return console.error(err.toString()); });

然后我们修改ValuesController文件,代码如下

[Route("api/[controller]")] [ApiController] public class ValuesController : ControllerBase { private ILogger _logger = null; public ValuesController(ILogger logger) { _logger = logger; } // GET api/values [HttpGet] public ActionResult Get() { _logger.LogTrace("User call the /api/values api"); _logger.LogDebug("User call the /api/values api"); _logger.LogInformation("User call the /api/values api"); _logger.LogWarning("User call the /api/values api"); _logger.LogError("User call the /api/values api"); _logger.LogCritical("User call the /api/values api"); return new string[] { "value1", "value2" }; } }

代码解释

我们创建了一个ValueController类的日志 当用户请求/api/values时,我们输出了6个不同级别的日志

最后我们修改Startup.cs中的Configure方法,使用我们之前介绍的方法,将SignalRLoggerProvider添加到管道中

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseStaticFiles(); loggerFactory.AddProvider(new SignalRLoggerProvider()); app.UseMvc(); } 最终效果

最后我们按照顺序,先启动SignalRServer, 再启动SignalRLoggerSample, 效果如下

本篇源代码

参考文献 MSDN: Logging in ASP.NET Core How to add custom logging in ASP.NET Core?


【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭